package zgrjb.snbq.teach_platform.service.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import zgrjb.snbq.teach_platform.config.AIConfig;
import zgrjb.snbq.teach_platform.dto.req.ChatRequest;
import zgrjb.snbq.teach_platform.service.ChatService;

import java.util.*;

@Service
@Slf4j
public class ChatServiceImpl implements ChatService {

    @Autowired
    private AIConfig aiConfig;
    
    @Autowired
    private RestTemplate restTemplate;
    
    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public String chat(String message) {
        try {
            Map<String, Object> requestBody = buildRequestBody(message);
            HttpEntity<Map<String, Object>> entity = buildHttpEntity(requestBody);
            
            log.info("🤖 发送AI请求: {}", message);
            
            ResponseEntity<String> response = restTemplate.postForEntity(
                aiConfig.getUrl(), entity, String.class);
            
            if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
                String responseContent = extractContentFromResponse(response.getBody());
                log.info("✅ AI响应成功: {}", responseContent.substring(0, Math.min(responseContent.length(), 100)));
                return responseContent;
            } else {
                log.error("❌ AI API调用失败: {}", response.getStatusCode());
            }
            
            return "抱歉，AI服务暂时不可用，请稍后再试。";
            
        } catch (Exception e) {
            log.error("❌ AI聊天失败: {}", e.getMessage(), e);
            return "抱歉，我暂时无法回答您的问题。请稍后再试。";
        }
    }

    @Override
    public void streamChat(String message, List<ChatRequest.FileInfo> files, StreamCallback callback) {
        try {
            // 构建包含文件信息的消息
            String enhancedMessage = buildEnhancedMessage(message, files);
            
            // 先获取完整响应，然后模拟流式发送
            String fullResponse = chat(enhancedMessage);
            
            // 模拟逐字符发送
            simulateStreamResponse(fullResponse, callback);
            
        } catch (Exception e) {
            log.error("流式聊天失败: {}", e.getMessage(), e);
            callback.onError(e);
        }
    }

    @Override
    public String generateQuestions(String prompt) {
        try {
            String enhancedPrompt = """
                请根据以下要求生成考试题目：
                %s
                
                请严格按照以下JSON格式生成3-5道题目：
                [
                  {
                    "type": "single",
                    "question": "题目内容",
                    "options": ["A. 选项1", "B. 选项2", "C. 选项3", "D. 选项4"],
                    "answer": "A",
                    "explanation": "解析内容",
                    "difficulty": "medium",
                    "points": 5
                  },
                  {
                    "type": "essay",
                    "question": "问答题内容",
                    "answer": "参考答案",
                    "explanation": "评分要点",
                    "difficulty": "hard",
                    "points": 15
                  }
                ]
                
                题目类型：single(单选)、multiple(多选)、judge(判断)、essay(简答)
                难度等级：easy(简单)、medium(中等)、hard(困难)
                """.formatted(prompt);
            
            return chat(enhancedPrompt);
            
        } catch (Exception e) {
            log.error("生成试题失败: {}", e.getMessage(), e);
            return "抱歉，试题生成失败，请稍后再试。";
        }
    }

    @Override
    public String analyzeData(Object data) {
        try {
            String prompt = """
                请分析以下教学数据，并提供专业的分析报告：
                %s
                
                请从以下几个方面进行分析：
                1. 数据概况总结
                2. 关键指标分析
                3. 趋势变化分析
                4. 存在的问题和风险
                5. 改进建议和措施
                
                请用中文回答，并尽量提供具体的数据支撑。
                """.formatted(data.toString());
            
            return chat(prompt);
            
        } catch (Exception e) {
            log.error("数据分析失败: {}", e.getMessage(), e);
            return "抱歉，数据分析失败，请稍后再试。";
        }
    }

    /**
     * 构建请求体
     */
    private Map<String, Object> buildRequestBody(String message) {
        Map<String, Object> body = new HashMap<>();
        body.put("model", aiConfig.getModel());
        
        List<Map<String, String>> messages = new ArrayList<>();
        
        // 添加系统消息
        Map<String, String> systemMessage = new HashMap<>();
        systemMessage.put("role", "system");
        systemMessage.put("content", "你是一个专业的教学助手，专门帮助师生解决教学和学习中的问题。请用中文回答，语言要专业但易懂。");
        messages.add(systemMessage);
        
        // 添加用户消息
        Map<String, String> userMessage = new HashMap<>();
        userMessage.put("role", "user");
        userMessage.put("content", message);
        messages.add(userMessage);
        
        body.put("messages", messages);
        body.put("stream", false);
        body.put("max_tokens", 2000);
        body.put("temperature", 0.7);
        body.put("top_p", 0.95);
        
        return body;
    }

    /**
     * 构建HTTP请求实体
     */
    private HttpEntity<Map<String, Object>> buildHttpEntity(Map<String, Object> body) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("Authorization", "Bearer " + aiConfig.getKey());
        
        return new HttpEntity<>(body, headers);
    }

    /**
     * 从响应中提取内容
     */
    private String extractContentFromResponse(String responseBody) {
        try {
            JsonNode jsonNode = objectMapper.readTree(responseBody);
            
            // 处理智谱AI的响应格式
            JsonNode choices = jsonNode.path("choices");
            if (choices.isArray() && choices.size() > 0) {
                JsonNode firstChoice = choices.get(0);
                JsonNode message = firstChoice.path("message");
                JsonNode content = message.path("content");
                
                if (!content.isMissingNode()) {
                    return content.asText();
                }
            }
            
            log.error("❌ 无法解析AI响应: {}", responseBody);
            return "抱歉，无法解析AI响应。";
            
        } catch (Exception e) {
            log.error("❌ 解析AI响应失败: {}", e.getMessage());
            return "抱歉，响应解析失败。";
        }
    }

    /**
     * 构建包含文件信息的增强消息
     */
    private String buildEnhancedMessage(String message, List<ChatRequest.FileInfo> files) {
        if (files == null || files.isEmpty()) {
            return message;
        }
        
        StringBuilder enhancedMessage = new StringBuilder(message);
        enhancedMessage.append("\n\n📎 附件信息：\n");
        
        for (ChatRequest.FileInfo file : files) {
            enhancedMessage.append(String.format("- 文件名：%s，类型：%s\n", 
                file.getName(), file.getType()));
        }
        
        enhancedMessage.append("\n请结合附件信息回答我的问题。");
        return enhancedMessage.toString();
    }

    /**
     * 模拟流式响应
     */
    private void simulateStreamResponse(String fullResponse, StreamCallback callback) {
        try {
            // 按字符分割，模拟打字机效果
            char[] chars = fullResponse.toCharArray();
            StringBuilder accumulated = new StringBuilder();
            
            for (char c : chars) {
                accumulated.append(c);
                callback.onContent(String.valueOf(c));
                
                // 模拟打字延迟
                Thread.sleep(20);
            }
            
            callback.onComplete(accumulated.toString());
            
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            callback.onError(e);
        } catch (Exception e) {
            callback.onError(e);
        }
    }
} 